feat: add trezor onchain event watcher#976
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b4fd96a304
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 018feaca8b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 58f11e5f04
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
# Conflicts: # gradle/libs.versions.toml
|
Synced with master to fix the pipe |
Watcher account-type detection can't reach
|
| Prefix (main/test) | AccountType |
|---|---|
xpub/tpub |
LEGACY (P2PKH) |
ypub/upub |
WRAPPED_SEGWIT (P2SH-P2WPKH) |
zpub/vpub |
NATIVE_SEGWIT (P2WPKH) |
This mapping is correct per SLIP-132. The catch: BIP86 taproot has no dedicated prefix — taproot accounts are serialized as plain xpub/tpub. So prefix auto-detection can never yield TAPROOT; a taproot key gets classified as LEGACY and watched as P2PKH (wrong address set), with no xpub-form prefix the user could supply to correct it.
bitkit-core already anticipates this — WatcherParams.accountType is a nullable override ("auto-detected from key prefix if None"). But TrezorRepo.startWatcher (TrezorRepo.kt:587) hardcodes accountType = null and doesn't accept an account-type argument, so the override is never reachable from this screen.
Same class of issue affects a native-segwit account exported in tpub form (instead of vpub): it silently watches the legacy address set.
Suggestion (optional, can be a follow-up): thread an AccountType? through startWatcher → WatcherParams.accountType and add a selector in WatcherSection (defaulting to prefix auto-detect). That makes taproot watchable and lets users override a misleading prefix.
Not blocking — flagging since the TAPROOT enum value is currently unreachable through the watcher UI.
Test vectors for reviewing the watcher
Mnemonic (test only, do not fund):
borrow shove play liberty someone menu acquire sauce damp hockey same ivory
Account-level extended keys (m/purpose'/coin'/0'), correctly prefixed per SLIP-132. Paste each into the watcher and confirm the detected Account Type:
| Account type | Path | Mainnet | Testnet/Regtest |
|---|---|---|---|
| LEGACY (P2PKH) | m/44'/x'/0' |
xpub6CdEcqzgLUGihHjVHLDdGpA39E5L3PSHau15T22nbS9Tknc6Ea9qeDcacD6hgJwC5h3oFA1XjrZSZNxqCAhTLLEUUubr1DTAkKXLjZK4n1E |
tpubDDmDh7gnRQvgFAy9iUYaqxp2ga7127uq3Dm4Ty2BLWfGzf1wE6wpMszUY7gVrHuTC1ipyW3gsrscxBy4JQo4cyBaWcaTqHk7y5BgK1LZpDr |
| WRAPPED_SEGWIT (P2SH-P2WPKH) | m/49'/x'/0' |
ypub6YGWPzNgmgu73wbNyzLm2pzkVyQnJuvEJvWPaFBNxfK16TCYd5Dveq6n4k74Zigo3mLXi2ZPoDeuMfpvWc6HFXsdobr7P1S3kVr2WXDSMA3 |
upub5EvnSNaUQddSNvdQwr6Dr52rSgMQtCNe2r5rABFaYyPJyruwAZZgreeaeqFGb9aD5Bk1f8odQDxiqLF8byb7mSf5xnQU3Af6xmcHJ3tR8Ro |
| NATIVE_SEGWIT (P2WPKH) | m/84'/x'/0' |
zpub6rvr6fTP1a9gwtMfGaYUMr3criSK8hHysUVk4SGKiBvyPuZyhTik5ytLGVVMjxxH1kbDdx7KQwKL91RYdhVABWzxbYkco1beZaJXtYBvCs3 |
vpub5ZY7nEBNhdQSwomKbQfTzZmHm7GgzNRV9v6T2j1FKJt77VvXWTxgN4yth6puqNSKK8JQdF2NCNgX75P9C1EzeSToYYMQbXtSqXSHR4KZX9Q |
| TAPROOT (P2TR)¹ | m/86'/x'/0' |
xpub6CETgoWxHvvPjmYAcw1WJjeqsZjZEXgZw1qc8ci9KkwUZ8HZTKsqxLvg13aFxegkpJ3gvBFCroeP486xuE5SGuRsnnrnhof1qcECBZKvS4s |
tpubDCzdfosztoepoTNmpiR7XbA9Wd67m8VDgsjiEeZcqjqZTa9eySaGCQTn4Z7JRkZ6qgnbHQvtsuYVqhqbTaKQPo3iAGXmWbUCMh4GSFkXMAS |
x' = 0' for mainnet, 1' for testnet/regtest.
¹ The taproot keys carry the xpub/tpub prefix (no BIP86-specific version bytes exist), so they will currently be detected as LEGACY — that's the gap described above.
Screen_recording_20260608_091038.webm
Addressed in this commit. |
There was a problem hiding this comment.
tAck
Tested on my Pixel 10 Android phone with my Trezor Safe 7 test device. I verified the dev-only Trezor Event Watcher flow end to end: connected the device, populated/used the xpub, started and stopped the watcher, and confirmed balance/transaction updates plus event log behavior worked as expected as I sent funds to a trezor device address then mined on regtest to see funds confirm.
Also validated network OFF + re-ON responsivity of the watcher on UI and in logic.
|
Additional Taproot/regtest coverage: Verified Joao’s account-type override case with Safe 7. Used a Bitcoin Testnet Taproot scrcpy.2026-06-08.006606.mp4 |
Adds an Event Watcher section to the (dev-only) Trezor screen that consumes the new bitkit-core on-chain xpub watcher. Enter or populate an extended key, start/stop a live watcher, and observe streaming balance, transactions, connection status, and an event log.
Depends on bitkit-core
0.1.65Description
WatcherSectioncomposable: extended-key + gap-limit inputs, populate-from-xpub, start/stop controls, and a live view of balance, transactions, connection status, and an event log.TrezorViewModel:WatcherEvents from the repo and maps them into a newTrezorWatcherState(balance, transactions, tx count, block height, account type, connection status, event log).watcherId, validates the xpub/gap-limit inputs, and surfaces errors via toasts.onCleared()so no watcher thread is leaked.TrezorRepo: exposes a bufferedwatcherEventsSharedFlowbridged from a coreEventListener, plusstartWatcher/stopWatcher/stopAllWatchersreturningResult<Unit>.TrezorService: thin wrappers overonchainStartWatcher/onchainStopWatcher/onchainStopAllWatchers.bitkit-coreto0.1.65inlibs.versions.toml.QA Notes
0.1.65.onCleared)../gradlew compileDevDebugKotlin,./gradlew testDevDebugUnitTest --tests TrezorViewModelTest --tests TrezorRepoTest,./gradlew detekt— all pass.